package vn.conghuy.talkwithme.responsor.responsor;

import java.util.ArrayList;

import vn.conghuy.talkwithme.MyApp;
import vn.conghuy.talkwithme.R;
import vn.conghuy.talkwithme.data.android.ContactModel;
import vn.conghuy.talkwithme.data.sqlmodel.SqlData;
import vn.conghuy.talkwithme.responsor.action.CallAction;
import vn.conghuy.talkwithme.utils.ArrayListContactWrapper;
import vn.conghuy.talkwithme.utils.IntWrapper;
import vn.conghuy.talkwithme.utils.Parser;
import vn.conghuy.talkwithme.utils.StringWrapper;
import vn.conghuy.talkwithme.utils.Utils;
import android.content.Context;

/**
 * 
 * NOTE :
 * Need call setCallAction before use.
 *
 */
public class CallResponsor extends Responsor {
	
	String address;
	ArrayList<ContactModel> listContact;
	ArrayList<ContactModel> lCallContact;
	
	
	private static final int RELATIVE_MISS_ADDRESS = 1;
	private static final int RELATIVE_ASK_CONTINUE_OR_NOT = 2;
	private static final int RELATIVE_ASK_CHOOSE_CONTACT = 3;

	private static final String TO_KEYWORD = "to";
	
	public CallResponsor(Context context)
	{
		super(context);
		MyApp myApp = (MyApp)context.getApplicationContext();
		listContact = myApp.listContact;
	}

	@Override
	public String response(String request) {
		
		if(Utils.isExistStringInArray(SqlData.stopWords, request) == true){
			relativeLastResponse = RELATIVE_NONE;
			return Utils.getRandomString(SqlData.callCancelPhrases);
		}
		
		switch (relativeLastResponse) {
		case RELATIVE_NONE:
			
			StringWrapper keyWordWrapper = new StringWrapper();
			if(Utils.isExistElemInArrayIsWordOfStr(SqlData.callKeywords, request, keyWordWrapper)){
				//get name after "call" or "call to"
				int indexOfKeyword = request.indexOf(keyWordWrapper.getStr());
				request = request.substring(indexOfKeyword);
				int nameIndex = Utils.indexOfWord(request, TO_KEYWORD);		//index of name, is words which after "to"
				if(nameIndex == -1)											//or if miss "to", get index after of call keyword
				{
					String keyword = keyWordWrapper.getStr();
					if(keyword == null) return null;
					nameIndex = Utils.indexOfWord(request, keyword);
					if(nameIndex != -1)
						nameIndex += keyword.length() + 1;
				}
				else{
					nameIndex += TO_KEYWORD.length() + 1;
				}
				
				String namePhrase;
				if(nameIndex < request.length())
					namePhrase = request.substring(nameIndex);
				else namePhrase = "";
				
				int result = callObjectInRequest(namePhrase);
				//if call success, finish
				if(result == Parser.PARSE_ADDRESS_OK){								
					relativeLastResponse = RELATIVE_NONE;
					return context.getString(R.string.call_command);
				}
				else if(result == Parser.PARSE_ADDRESS_MULTI){
					relativeLastResponse = RELATIVE_ASK_CHOOSE_CONTACT;
					return responseStringToSelectMultiContact();
				}
				//else tell name is not exist and finish
				else if(result == Parser.PARSE_ADDRESS_FAIL){
					relativeLastResponse = RELATIVE_ASK_CONTINUE_OR_NOT;
					return Utils.getRandomString(SqlData.callNameNotExistPhrase);
				}
			}
			
			break;

		//tell name to call again
		case RELATIVE_MISS_ADDRESS:

			//call
			int result = callObjectInRequest(request);
			if(result == Parser.PARSE_ADDRESS_OK){
				relativeLastResponse = RELATIVE_NONE;
				return context.getString(R.string.call_command);
			}
			else if(result == Parser.PARSE_ADDRESS_MULTI){
				relativeLastResponse = RELATIVE_ASK_CHOOSE_CONTACT;
				return responseStringToSelectMultiContact();
			}
			else if(result == Parser.PARSE_ADDRESS_FAIL){
				relativeLastResponse = RELATIVE_ASK_CONTINUE_OR_NOT;
				return Utils.getRandomString(SqlData.callNameNotExistPhrase);
			}
			
		//ask continue tell or not
		case RELATIVE_ASK_CONTINUE_OR_NOT:
			result = callObjectInRequest(request);
			if(result == Parser.PARSE_ADDRESS_OK){
				relativeLastResponse = RELATIVE_NONE;
				return context.getString(R.string.call_command);
			}
			else if(result == Parser.PARSE_ADDRESS_MULTI){
				relativeLastResponse = RELATIVE_ASK_CHOOSE_CONTACT;
				return responseStringToSelectMultiContact();
			}
			else if(result == Parser.PARSE_ADDRESS_FAIL){
				if(Utils.isExistElemInArrayIsWordOfStr(SqlData.callYesWords, request, null)){
					relativeLastResponse = RELATIVE_MISS_ADDRESS;
					return Utils.getRandomString(SqlData.callAskOtherNamePhrases);
				}
				else if (Utils.isExistElemInArrayIsWordOfStr(SqlData.callNoWords, request, null)){
					relativeLastResponse = RELATIVE_NONE;
					return Utils.getRandomString(SqlData.callCancelPhrases);
				}
				else{		// "talk with me" think you are joking.
					relativeLastResponse = RELATIVE_NONE;
					return Utils.getRandomString(SqlData.callJokePhrases);
				}
			}
			
		case RELATIVE_ASK_CHOOSE_CONTACT:
			ContactModel contact = ContactModel.isExistElemInArrayHasNameBeSubStringOfStr(lCallContact, request);
			if(contact != null){
				CallAction callAction = new CallAction(context, contact.getAddress());
				callAction.doAction();
				relativeLastResponse = RELATIVE_NONE;
				return context.getString(R.string.call_command);
			}
			else{
				IntWrapper numberWrapper = new IntWrapper();
				if(Utils.hasNumber(request, numberWrapper)){
					int number = numberWrapper.getInt();
					if(number <= lCallContact.size() + 1){
						contact = lCallContact.get(number - 1);
						CallAction callAction = new CallAction(context, contact.getAddress());
						callAction.doAction();
						relativeLastResponse = RELATIVE_NONE;
						return context.getString(R.string.call_command);
					}
				}
				
				//final else
				relativeLastResponse = RELATIVE_ASK_CHOOSE_CONTACT;
				return responseStringToSelectMultiContact();
			}
		default:
			break;
		}
		super.response(request);
		return null;
	}

	@Override
	public int relativeWithLastRequest(String sentence) {
		return relativeLastResponse;
	}
	
	private int callObjectInRequest(String namePhrase){
		StringWrapper addressWrapper = new StringWrapper();
		ArrayListContactWrapper lCallContactWrapper = new ArrayListContactWrapper();
		int result = Parser.parseAddressFromNamePhrase(namePhrase, listContact, lCallContactWrapper, addressWrapper);
		address = addressWrapper.getStr();
		lCallContact = lCallContactWrapper.getArrayList();
		if(result == Parser.PARSE_ADDRESS_FAIL || result == Parser.PARSE_ADDRESS_MULTI) return result;
		CallAction callAction = new CallAction(context, address);
		callAction.doAction();
		return result;
	}
	
	private String responseStringToSelectMultiContact(){
		String responseString = Utils.getRandomString(SqlData.commonAskChooseContact) + " ";
		int i = 0;
		for(ContactModel contactModel:lCallContact){
			responseString += "\n" + (i+1) + " - " + contactModel.getName() + ", ";
			i++;
		}
		responseString = responseString.substring(0, responseString.length() - 2);
		return responseString;
	}
	
	@Override
	public int indexOfMainVerb(String request) {
		StringWrapper keyWordWrapper = new StringWrapper();
		if(Utils.isExistElemInArrayIsWordOfStr(SqlData.callKeywords, request, keyWordWrapper))
			return Utils.indexOfWord(request, keyWordWrapper.getStr());
		else return super.indexOfMainVerb(request);
	}

}
